package com.islewars.client.mapEditor;

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.canvas.client.Canvas;
import com.google.gwt.canvas.dom.client.Context2d;
import com.google.gwt.canvas.dom.client.CssColor;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HasAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.islewars.client.Calculation;
import com.islewars.client.ClientStaticData;
import com.islewars.client.MountainType;
import com.islewars.client.Vector;
import com.islewars.client.dto.MountainDto;
import com.islewars.client.lobby.Lobby;
import com.islewars.client.service.GameService;
import com.islewars.client.service.GameServiceAsync;

public class MapEditor {
	private Canvas canvas;
	private Context2d context;
	private static final int canvasWidth = 700;
	private static final int canvasHeight = 700;
	private List<MountainDto> mountains;
	private static GameServiceAsync gameServiceAsync = GWT.create(GameService.class);

	public MapEditor() {
		init();
	}

	private void init() {
		HorizontalPanel mainHorizontalPanel = new HorizontalPanel();
		mainHorizontalPanel.setWidth("80%");
		mainHorizontalPanel.setHeight(Window.getClientHeight() + "px");
		((HorizontalPanel) mainHorizontalPanel).setHorizontalAlignment(HasAlignment.ALIGN_CENTER);

		canvas = Canvas.createIfSupported();

		if (canvas == null) {
			RootPanel.get().add(new Label("Sorry, your browser doesn't support the HTML5 Canvas element"));
			return;
		}

		canvas.setStyleName("mainCanvas");
		canvas.setWidth(canvasWidth + "px");
		canvas.setCoordinateSpaceWidth(canvasWidth);

		canvas.setHeight(canvasHeight + "px");
		canvas.setCoordinateSpaceHeight(canvasHeight);

		mainHorizontalPanel.add(canvas);

		context = canvas.getContext2d();

		mountains = new ArrayList<MountainDto>();

		VerticalPanel verticalPanel = new VerticalPanel();

		final TextBox gameNameTextBox = new TextBox();
		gameNameTextBox.setTitle("Game name");
		gameNameTextBox.setText("Island");
		verticalPanel.add(gameNameTextBox);

		final ListBox mountainsListBox = new ListBox();
		mountainsListBox.setTitle("Mountain type");
		for (MountainType mountainType : MountainType.values()) {
			mountainsListBox.addItem(mountainType.name());
		}
		verticalPanel.add(mountainsListBox);

		final TextBox radiusTextBox = new TextBox();
		radiusTextBox.setTitle("Mountain radius");
		radiusTextBox.setText("300");
		verticalPanel.add(radiusTextBox);

		final TextBox heightTextBox = new TextBox();
		radiusTextBox.setTitle("Mountain height");
		heightTextBox.setText("300");
		verticalPanel.add(heightTextBox);

		Button createButton = new Button("Create game");
		createButton.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				gameServiceAsync.createGame(ClientStaticData.player, gameNameTextBox.getText(), mountains, new AsyncCallback<Boolean>() {
					@Override
					public void onSuccess(Boolean result) {
						new Lobby();
					}
					
					@Override
					public void onFailure(Throwable caught) {
						caught.printStackTrace();
					}
				});
			}
		});
		verticalPanel.add(createButton);
		
		mainHorizontalPanel.add(verticalPanel);

		RootPanel.get().setStyleName("rootStyle");
		RootPanel.get().clear();
		RootPanel.get().add(mainHorizontalPanel);

		canvas.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				MountainDto mountain = new MountainDto();
				mountain.x = event.getX();
				mountain.y = event.getY();
				mountain.type = MountainType.valueOf(mountainsListBox.getValue(mountainsListBox.getSelectedIndex()));
				mountain.radius = Integer.parseInt(radiusTextBox.getText());
				mountain.height = Integer.parseInt(heightTextBox.getText());
				mountains.add(mountain);

				draw();
			}
		});
		
		context.setFillStyle(CssColor.make(0, 160, 0));
		context.fillRect(0, 0, canvasWidth, canvasHeight);
	}

	private void draw() {
		for (int x = 0; x < canvasWidth; x += 10) {
			for (int y = 0; y < canvasHeight; y += 10) {
				double height = Calculation.getHeight(new Vector(x, y), mountains);
				context.setFillStyle(CssColor.make((int) height/2, 160, 0));
				context.fillRect(x, y, 10, 10);
			}
		}
	}
}
